package partner

import (
	"chess_platform/internal/alisdk"
	. "chess_platform/internal/common"
	"chess_platform/internal/login/fetch"
	"fmt"
	"github.com/boombuler/barcode"
	"github.com/boombuler/barcode/qr"
	"github.com/golang/freetype"
	"image"
	"image/color"
	"image/draw"
	"image/jpeg"
	"image/png"
	"io/ioutil"
	"os"
)

//生成下载APP的登录界面
func MakeLoginQRCode2(uid int64, headImgUrl, typeName string) (string, error) {
	filename := fmt.Sprintf("pf_login-%d.png", uid)
	content := fmt.Sprintf("%v?agent_uid=%v", QRCode.LoginUrl, uid)
	qrCode, _ := qr.Encode(content, qr.H, qr.Auto)
	qrCode, _ = barcode.Scale(qrCode, 620, 620)
	file, _ := os.Create(filename)
	defer file.Close()
	png.Encode(file, qrCode)

	imgb, err := os.Open(filename)
	if err != nil {
		return "", err
	}
	defer imgb.Close()
	//defer os.Remove(filename)

	var f *os.File
	f = imgb

	//用户有头像，下载头像
	if headImgUrl != "" {
		word := fmt.Sprintf("小胜跑得快,祝您玩得开心")
		img, _ := png.Decode(imgb)
		t, err := HandleImg(headImgUrl, word, typeName, uid, img)
		if err != nil {
			LogPF.Error(err.Error())
		} else {
			f = t
		}
	}

	ossPath, err := alisdk.UploadFileToOss(f, filename, PlatformRunMode+"/qr_code/pf_login", uid)
	if err != nil {
		return "", err
	}
	data := map[string]interface{}{
		"login_url": ossPath,
	}
	_, err = UpdateUser(data, uid)
	return ossPath, err
}

//生成总代(一级代理),二级代理,三级代理的个人名片
func MakePfQRCode(uid int64, headImgUrl, typeName string) (string, error) {
	filename := fmt.Sprintf("pf_name-%d.png", uid)
	content := fmt.Sprintf("%v?pid=%v&group_id=0", QRCode.PfNameUrl, uid)
	qrCode, _ := qr.Encode(content, qr.H, qr.Auto)
	qrCode, _ = barcode.Scale(qrCode, 620, 620)
	file, _ := os.Create(filename)
	defer file.Close()
	err := png.Encode(file, qrCode)
	if err != nil {
		LogPF.Error(fmt.Sprintf("生成二维码时出错:%v", err))
		return "", err
	}

	imgb, err := os.Open(filename)
	if err != nil {
		return "", err
	}
	defer imgb.Close()
	//defer os.Remove(filename)

	var f *os.File
	f = imgb

	//用户有头像，下载头像
	if headImgUrl != "" {
		word := fmt.Sprintf("小胜合伙人,欢迎您加入代理")
		img, err := png.Decode(imgb)
		if err != nil {
			LogPF.Error(fmt.Sprintf("解析合伙人代理(ID:%v)头像时出错:%v", uid, err))
			return "", err
		}
		t, err := HandleImg(headImgUrl, word, typeName, uid, img)
		if err != nil {
			LogPF.Error(err.Error())
		} else {
			f = t
		}
	}

	ossPath, err := alisdk.UploadFileToOss(f, filename, PlatformRunMode+"/qr_code/pf_name", uid)
	if err != nil {
		return "", err
	}
	data := map[string]interface{}{
		"name_url": ossPath,
	}
	_, err = UpdateUser(data, uid)
	return ossPath, err
}

func HandleImg(headImgUrl, word, typ string, uid int64, img image.Image) (*os.File, error) {
	//step 3: 下载微信头像
	data, err := fetch.Cmd(fetch.Request{
		Method: "GET",
		URL:    headImgUrl,
	})
	if err != nil {
		LogPF.Error(fmt.Sprintf("下载用户(ID:%v)头像失败:%v", uid, err))
		return nil, err
	}
	logoName := fmt.Sprintf("wechat-%v-%v.jpg", typ, uid)
	err = ioutil.WriteFile(logoName, data, 0666)
	if err != nil {
		LogPF.Error(fmt.Sprintf("创建用户(ID:%v)微信头像文件失败:%v", uid, err))
		return nil, err
	}

	//step 4:打开微信头像图片,以jpg格式打开
	logoB, err := os.Open(logoName)
	if err != nil {
		LogPF.Error(fmt.Sprintf("打开用户(ID:%v)微信头像文件失败:%v", uid, err))
		return nil, err
	}
	logoImg, imageType, err := image.Decode(logoB)
	if err != nil {
		LogPF.Error(fmt.Sprintf("解析用户(ID:%v)微信头像(类型:%v)时失败:%v", uid, imageType, err))
		return nil, err
	}
	defer logoB.Close()

	//step 5: 生成文字图片
	filename := fmt.Sprintf("word-%v-%v.jpg", typ, uid)
	AddTextToImage(word, filename)
	//step 6: 打开文字图片,以jpg格式编码
	wordB, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	wordImg, _, err := image.Decode(wordB)
	if err != nil {
		return nil, err
	}
	defer wordB.Close()

	//step 7: 计算logo与二维码之间的相对位置
	offsetLogo := image.Pt((img.Bounds().Dx()-logoImg.Bounds().Dx())/2, (img.Bounds().Dy()-logoImg.Bounds().Dy())/2)
	// 计算文字图片与二维码之间的相对位置
	offsetWord := image.Pt(0, 620)
	//二维码的边界
	b := img.Bounds()

	//step 8: 创建一个图
	m := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy()+70))
	for y := 0; y < b.Dy()+80; y++ {
		for x := 0; x < b.Dx(); x++ {
			//设置一块 白色(255,255,255)不透明的背景
			m.Set(x, y, color.RGBA{255, 255, 255, 255})
		}
	}
	draw.Draw(m, b, img, image.ZP, draw.Src)
	draw.Draw(m, logoImg.Bounds().Add(offsetLogo), logoImg, image.ZP, draw.Over)
	draw.Draw(m, wordImg.Bounds().Add(offsetWord), wordImg, image.ZP, draw.Over)

	newName := fmt.Sprintf("new-name-%v-%v.jpg", typ, uid)
	imgN, _ := os.Create(newName)
	jpeg.Encode(imgN, m, &jpeg.Options{100})
	defer imgN.Close()
	f, err := os.Open(newName)
	return f, err
}

//添加文本到图片
func AddTextToImage(word, filename string) (string, error) {
	//图片的宽度
	dx := 620
	//图片的高度
	dy := 70

	img := image.NewNRGBA(image.Rect(0, 0, dx, dy))
	//设置每个点的 RGBA (Red,Green,Blue,Alpha(设置透明度))
	for y := 0; y < dy; y++ {
		for x := 0; x < dx; x++ {
			//设置一块 白色(255,255,255)不透明的背景
			img.Set(x, y, color.RGBA{255, 255, 255, 255})
		}
	}

	//读取字体数据
	fontBytes, err := ioutil.ReadFile("conf/simkai.ttf")
	if err != nil {
		return "", err
	}
	//载入字体数据
	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		return "", err
	}
	f := freetype.NewContext()
	//设置分辨率
	f.SetDPI(72)
	//设置字体
	f.SetFont(font)
	//设置尺寸
	f.SetFontSize(26)
	f.SetClip(img.Bounds())
	//设置输出的图片
	f.SetDst(img)
	//设置字体颜色(红色)
	f.SetSrc(image.NewUniform(color.RGBA{0, 0, 0, 255}))

	//设置字体的位置
	pt := freetype.Pt(170, 40+int(f.PointToFixed(26))>>8)

	_, err = f.DrawString(word, pt)
	if err != nil {
		return "", err
	}
	imgfile, _ := os.Create(filename)
	defer imgfile.Close()
	jpeg.Encode(imgfile, img, &jpeg.Options{100})
	return filename, nil
}
